#pragma once
#include <random>
#include <time.h>
#include "d3dUtil.h"
#include "GraphicalEntity.h"
#include "PhysicsObjects.h"
#include "Planet.h"
#include "Missile.h"
#include "Ship.h"
#include "Bot.h"
#include "Railgun.h"
#include "Skybox.h"

#define RANDOM_MAX 10000
#define RANDOM_MIN -10000

struct GameModel
{
	std::string FileName;
	ID3DXMesh *MainModel;
	DWORD NumberMaterials;
	LPD3DXBUFFER MaterialBuffer;

	GameModel()
	{
		FileName = "";
		MainModel = NULL;
		MaterialBuffer = NULL;
	}

	~GameModel()
	{
		if(MainModel)
		{
			MainModel->Release();
			MainModel = NULL;
		}
		if(MaterialBuffer)
		{
			MaterialBuffer->Release();
			MaterialBuffer = NULL;
		}
	}
};

struct GameTexture
{
	std::string FileName;
	IDirect3DTexture9* MainTexture;

	GameTexture()
	{
		FileName = "";
		MainTexture = NULL;
	}

	~GameTexture()
	{
		if(MainTexture)
		{
			MainTexture->Release();
			MainTexture = NULL;
		}
	}
};

class _Globals
{
public:
	std::vector<Planet*> Planets;
	std::vector<Bot*> Bots;

	Skybox *SpaceBox;

	TestShip *Player;

	BaseMissile *Missile;

	//Matrices for random stuff
	D3DXMATRIX M1,
			   M2,
			   M3;

	std::vector<GameTexture*> GameTextures;
	std::vector<GameModel*> GameModels;

public:
	_Globals( void );
	~_Globals();

	void AddPlanet(IDirect3DDevice9 *nDevice, D3DXVECTOR3 nPosition, D3DXVECTOR3 nScale,
                     D3DXVECTOR3 RotationSpeed, float nRadius, std::string Filename);

	void AddBot(IDirect3DDevice9 *nDevice, float nMass, State *nState, D3DXVECTOR3 BotSize,
		          float nThrust);

	void Update(float dt);
	void Render( void );
	bool CheckSpawnCollision(Planet* P1, Planet *P2);

	void CleanUpModelList( void );

};

struct _Random
{
	std::tr1::uniform_int<> IntGenerator;
	std::tr1::uniform_real<> DoubleGenerator;
	std::tr1::mt19937_64 MersEngine;

	_Random()
	{
		MersEngine.seed(UINT(time(NULL)));
	}
};

extern _Random *Random;
extern _Globals *Globals;